import { fromEvent } from "rxjs";
import {
  concatMap,
  filter,
  first,
  map,
  mergeWith,
  switchMap,
  takeUntil,
  tap,
  throttleTime,
} from "rxjs/operators";

const messageElement = document.querySelector(".message");

const log = (x) => (messageElement.textContent = x);

class Box {
  public el: HTMLElement;

  constructor(color: string) {
    const d = document.createElement("div");
    d.className = "box";
    d.style.position = "fixed";
    d.style.width = "100px";
    d.style.height = "100px";
    d.style.left = "0";
    d.style.top = "0";
    d.style.backgroundColor = color;
    d.style.cursor = "pointer";
    d.title = "drag me";
    this.el = d;
  }

  move(dir: "up" | "down" | "left" | "right", offset: number) {
    const el = this.el;
    switch (dir) {
      case "up":
        el.style.top = el.offsetTop - offset + "px";
        break;
      case "down":
        el.style.top = el.offsetTop + offset + "px";
        break;
      case "left":
        el.style.left = el.offsetLeft - offset + "px";
        break;
      case "right":
        el.style.left = el.offsetLeft + offset + "px";
        break;
      default:
        throw new Error("unknown dir");
    }
    return this;
  }
  attach() {
    document.body.appendChild(this.el);
  }
}

let zIndex = 0;

const b1 = new Box("red").attach();
const b2 = new Box("green").move("down", 10).move("right", 10).attach();
const b3 = new Box("blue").move("down", 20).move("right", 20).attach();

const mouseDown$ = fromEvent<MouseEvent>(window, "mousedown");
const mouseMove$ = fromEvent<MouseEvent>(window, "mousemove");
const mouseUp$ = fromEvent<MouseEvent>(window, "mouseup");

mouseMove$.subscribe(e => {
  console.log("--", e.x, e.y);
})

mouseDown$
  .pipe(
    filter((d) => (d.target as HTMLElement).className.includes("box")),
    tap((d) => {
      const el = (d.target as HTMLElement);
      console.log("DOWN: " + el.style.backgroundColor);
    }),
    switchMap((d) => {
      const el = d.target as HTMLElement;
      zIndex++;
      el.style.zIndex = zIndex + "";

      const initialX = d.offsetX;
      const initialY = d.offsetY;
      // const mouseOut$ = fromEvent<MouseEvent>(el, "mouseout");
      return mouseMove$.pipe(
        tap((e) => {
          const el = e.target as HTMLElement;
          console.log("==>", e.x, e.y);
          console.log('e', e);
        }),
        // throttleTime(50),
        takeUntil(mouseUp$),
        map((e) => ({ el, pos: [e.x - initialX, e.y - initialY] })),
      );
    })
  )
  .subscribe(({ el, pos: [x, y] }) => {
    el.style.left = x + "px";
    el.style.top = y + "px";
  });
